//package cn.foolishbird.crow.mybatis.plus.typehandler;
//
//import cn.foolishbird.crow.core.CrowEnum;
//import cn.foolishbird.crow.enumeration.CrowEnumUtils;
//import org.apache.ibatis.type.BaseTypeHandler;
//import org.apache.ibatis.type.JdbcType;
//import org.apache.ibatis.type.MappedJdbcTypes;
//import org.apache.ibatis.type.MappedTypes;
//
//import java.sql.CallableStatement;
//import java.sql.PreparedStatement;
//import java.sql.ResultSet;
//import java.sql.SQLException;
//
///**
// * @author foolish-bird
// * @version 1.0
// * @date 2021-05-11
// */
//@MappedTypes(CrowEnum.class)
//@MappedJdbcTypes(JdbcType.INTEGER)
//public class CrowEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
//
//    private final Class<E> type;
//    private final E[] enums;
//
//    public CrowEnumTypeHandler(Class<E> type) {
//        if (type == null) {
//            throw new IllegalArgumentException("Type argument cannot be null");
//        }
//        this.type = type;
//        this.enums = type.getEnumConstants();
//    }
//
//    @Override
//    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
//        if (parameter instanceof CrowEnum) {
//            CrowEnum s = (CrowEnum) parameter;
//            ps.setInt(i, s.value());
//        } else {
//            ps.setInt(i, parameter.ordinal());
//        }
//    }
//
//    @Override
//    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
//        int value = rs.getInt(columnName);
//        if (value == 0 && rs.wasNull()) {
//            return null;
//        }
//        if (CrowEnum.class.isAssignableFrom(this.type)) {
//            return this.toValueEnum(value);
//        } else {
//            return toOrdinalEnum(value);
//        }
//    }
//
//    @Override
//    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
//        int value = rs.getInt(columnIndex);
//        if (value == 0 && rs.wasNull()) {
//            return null;
//        }
//        if (CrowEnum.class.isAssignableFrom(this.type)) {
//            return this.toValueEnum(value);
//        } else {
//            return toOrdinalEnum(value);
//        }
//    }
//
//    @Override
//    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
//        int value = cs.getInt(columnIndex);
//
//        if (value == 0 && cs.wasNull()) {
//            return null;
//        }
//        if (CrowEnum.class.isAssignableFrom(this.type)) {
//            return this.toValueEnum(value);
//        } else {
//            return this.toOrdinalEnum(value);
//        }
//    }
//
//    /**
//     * @param ordinal
//     * @return E
//     * @throws
//     * @author foolish-bird
//     * @date 2021/5/12
//     **/
//    private E toOrdinalEnum(int ordinal) {
//        try {
//            return enums[ordinal];
//        } catch (Exception ex) {
//            throw new IllegalArgumentException("Cannot convert " + ordinal + " to " + type.getSimpleName() + " by ordinal value.", ex);
//        }
//    }
//
//}
